# a lightweight vec class

import math

class Vector:
	# initializes vec self
	def __init__(self, vector):
		self.vec = vector
		self.i = vector[0]
		self.j = vector[1]
		self.k = vector[2]
		
	# rotates vector self around character axis by numeric value radians
	def rotate(self, axis, radians):

		sin = math.sin(radians)
		cos = math.cos(radians)

		if axis == 'x':
			newVec = [self.i, self.j * cos - self.k * sin, self.j * sin + self.k * cos]
			return Vector(newVec)
		elif axis == 'y':
			newVec = [self.k * sin + self.i * cos, self.j, self.k * cos - self.i * sin]
			return Vector(newVec)
		elif axis == 'z':
			newVec = [self.i * cos - self.j * sin, self.i * sin + self.j * cos, self.k]
			return Vector(newVec)
		else:
			return "null"
		
		#self.updateIJK()

	# adds vector other to vector self
	def add(self, other):
		newVec = [self.i + other.i, self.j + other.j, self.k + other.k]
		return Vector(newVec)

	# subtracs vector other from vector self
	def subtract(self, other):
		newVec = [self.i - other.i, self.j - other.j, self.k - other.k]
		return Vector(newVec)

	# normalizes vector self
	def normalize(self):
		mag = self.getMagnitude()
		newVec = self.vec
		if mag != 0:
			newVec = [self.i/mag, self.j/mag, self.k/mag]
		return Vector(newVec)
	
	# divides vector self by numeric constant
	def divConstant(self, constant):
		if constant != 0:
			newVec = [self.i / constant, self.j / constant, self.k / constant]
			return Vector(newVec)
		else:
			return "null"
	
	# multiplies vector self by numeric constant
	def multConstant(self, constant):
		newVec = [self.i * constant, self.j * constant, self.k * constant]
		return Vector(newVec)
	
	# adds numeric constant to vector self
	def addConstant(self, constant):
		newVec = [self.i + constant, self.j + constant, self.k + constant]
		return Vector(newVec)
	
	# applies numeric magnitude to vector self
	def setMagnitude(self, magnitude):
		newVec = self.normalize()
		newVec = self.multConstant(magnitude)
		return newVec

	# returns numeric magnitude of vector self
	def getMagnitude(self):
		return math.sqrt((self.i * self.i) + (self.j * self.j) + (self.k * self.k))

	# returns numeric dot prodct of vectors self and other
	def dot(self, other):
		return self.i * other.i + self.j * other.j + self.k * other.k
	
	def cross(self, other):
		i = (self.j * other.k - self.j * other.k)
		j = (self.k * other.i - self.k * other.i)
		k = (self.i * other.j - self.i * other.j)
		return Vector([i, j, k])
	
	# returns numeric radian angle between vectors self and other
	def angleBetween(self, axis, other):
		v1 = self.normalize()
		v2 = other.normalize()
		
		if axis == 'x':
			return math.atan2(v1.k * v2.j - v1.j * v2.k, v1.k * v2.k + v1.j * v2.j) - math.pi
		elif axis == 'y':
			return math.atan2(v1.i * v2.k - v1.k * v2.i, v1.i * v2.i + v1.k * v2.k) - math.pi
		elif axis == 'z':
			return math.atan2(v1.i * v2.j - v1.j * v2.i, v1.i * v2.i + v1.j * v2.j) - math.pi
		else:
			return "null"
	
	def generalAngleBetween(self, other):
		v1 = self.normalize()
		v2 = other.normalize()
		
		return math.acos(self.dot(other) / self.getMagnitude() * other.getMagnitude())
		
	# returns a duplicated vector
	def duplicate(self):
		return Vector(self.vec)
	
	# keeps numeric values i, j, and k up to date
	def updateIJK(self):
		self.i = self.vec[0]
		self.j = self.vec[1]
		self.k = self.vec[2]